package com.nys.cqhttp.message.factory;

import java.util.*;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import com.nys.cqhttp.mapper.FilterMassageMapper;
import com.nys.cqhttp.mapper.MassageMapper;
import com.nys.cqhttp.message.factory.impl.TianQiMessageHandler;
import com.nys.cqhttp.model.FilterMassage;
import com.nys.cqhttp.model.FilterMassageExample;
import com.nys.cqhttp.model.Massage;
import com.nys.cqhttp.model.MassageExample;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.nys.cqhttp.constant.CommonConstant;
import com.nys.cqhttp.message.factory.impl.DefaultMessageHandler;
import com.nys.cqhttp.param.Context;
import com.nys.cqhttp.param.MessageParam;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * MessageFactory
 *
 * @author nysheng
 * @version 1.0.0
 * @description 消息工厂-获取自动回复的消息内容
 * @date 2021/12/28 13:53
 */
@Component
@Slf4j
public class MessageFactory {

  @Autowired private MassageMapper massageMapper;
  private static MessageFactory messageFactory;
  @Autowired private FilterMassageMapper filterMassageMapper;

  private static Map<String, IMessageHandler> messageHandlerMap = new HashMap<>();

  @PostConstruct
  private void init() {
    messageHandlerMap.put("default", new DefaultMessageHandler());
    messageFactory = this;
    massageMapper = this.massageMapper;
    filterMassageMapper = this.filterMassageMapper;
  }

  private IMessageHandler loadIMessageHandler(String path) {
    return messageHandlerMap.computeIfAbsent(
        path,
        k -> {
          try {
            Class<IMessageHandler> aClass = (Class<IMessageHandler>) Class.forName(k);

            return aClass.getConstructor().newInstance();
          } catch (Exception e) {
            log.error("反射生成类失败", e);
            return null;
          }
        });
  }

  public List<String> getMessage(MessageParam messageParam) {
    try {

      List<String> messageList = new ArrayList<>();
      Context context = Context.builder().messageParam(messageParam).build();
      // 处理参数
      String message = messageParam.getMessage();
      final StringBuilder suffixBuilder = new StringBuilder();
      if (message.contains("+")) {
        int index = message.indexOf("+");
        if (message.length() > index + 1) {
          String suffix = message.substring(index + 1);
          if (suffix.matches("\\d+")) {
            context.setIndex(Integer.parseInt(suffix));
          }
          suffixBuilder.append(suffix);
        }
        messageParam.setMessage(message.substring(0, index));
      }
      MassageExample massageExample = new MassageExample();
      MassageExample.Criteria criteria = massageExample.createCriteria();
      criteria.andUserEqualTo(messageParam.getSelfId());
      criteria.andKeywordEqualTo(messageParam.getMessage());
      List<Massage> massages = messageFactory.massageMapper.selectByExample(massageExample);
      if (CollectionUtils.isEmpty(massages)) {
        int i = message.indexOf("-");
        if (i != -1) {
          int i1 = message.indexOf(".-");
          if (i1 > -1) {
            MassageExample massageExample1 = new MassageExample();
            MassageExample.Criteria criteria1 = massageExample1.createCriteria();
            criteria1.andUserEqualTo(messageParam.getSelfId());
            criteria1.andKeywordEqualTo(".-");
            massages = messageFactory.massageMapper.selectByExample(massageExample1);
          } else {
            MassageExample massageExample1 = new MassageExample();
            MassageExample.Criteria criteria1 = massageExample1.createCriteria();
            criteria1.andUserEqualTo(messageParam.getSelfId());
            criteria1.andKeywordEqualTo(message.substring(0, i));
            massages = messageFactory.massageMapper.selectByExample(massageExample1);
          }
        } else {
          if (CollectionUtils.isEmpty(massages)) {
            FilterMassageExample example = new FilterMassageExample();
            FilterMassageExample.Criteria criteria1 = example.createCriteria();
            criteria1.andUserEqualTo(messageParam.getSelfId());
            List<FilterMassage> filterMassages =
                messageFactory.filterMassageMapper.selectByExample(example);
            for (FilterMassage filterMassage : filterMassages) {
              if (filterMassage.getType() == 2) {
                if (messageParam.getMessage().contains(filterMassage.getValue())) {
                  return Arrays.asList("");
                }
              } else {
                if (StringUtils.equals(filterMassage.getValue(), messageParam.getMessage())) {
                  return Arrays.asList("");
                }
              }
            }
            MassageExample massageExample2 = new MassageExample();
            MassageExample.Criteria criteria2 = massageExample2.createCriteria();
            criteria2.andKeywordEqualTo(CommonConstant.STR_JQR_FF);
            massages = messageFactory.massageMapper.selectByExample(massageExample2);
          }
        }
      }

      massages.forEach(
          massage -> {
            List<String> senderList = Arrays.asList(massage.getSender().split(","));
            if (senderList.contains("all") || senderList.contains(messageParam.getSenderId())) {
              if (StringUtils.equals(CommonConstant.STR_DISPLAY, suffixBuilder.toString())) {
                List<String> list =
                    loadIMessageHandler(massage.getHandler()).listHandler(massage, context);
                log.info(list.toString());
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < list.size(); i++) {
                  if (sb.toString().length() + list.get(i).length()
                      > CommonConstant.MESSAGE_MAX_LENGTH) {
                    messageList.add(sb.toString());
                    sb = new StringBuilder();
                  }
                  sb.append(i + 1).append("：").append(list.get(i)).append("\r\n-------------\r\n");
                }
                messageList.add(sb.toString());
              } else {
                String result;
                result = loadIMessageHandler(massage.getHandler()).handler(massage, context);
                while (result.length() > CommonConstant.MESSAGE_MAX_LENGTH) {
                  messageList.add(result.substring(0, CommonConstant.MESSAGE_MAX_LENGTH) + "\r\n");
                  result = result.substring(CommonConstant.MESSAGE_MAX_LENGTH);
                }
                messageList.add(result);
              }
            }
          });
      if (CollectionUtils.isEmpty(messageList)) {
        List<String> list =
            Arrays.asList("你到底在说甚么呀~", "啊这，俺听8懂", "发送菜单就能获取帮助啦", "呜呜呜，我听不懂啦~", "呵，真是人类难以理解的话语呢");
        return Arrays.asList(list.get(new Random().nextInt(list.size())));
      }
      return messageList;
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
  }
}
